package com.example.nextgen.io;

import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.file.FileCopier;
import cn.hutool.core.io.file.FileReader;
import cn.hutool.core.io.file.FileWriter;
import cn.hutool.core.util.StrUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import com.example.nextgen.parser.excel.ExcelParser;
import com.example.nextgen.parser.excel.model.ExcelParserResult;
import com.example.nextgen.generator.GenerateResult;
import org.springframework.stereotype.Component;

import java.io.File;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

/**
 * @author martin
 * @date Created in 2022/11/10 16:47
 * @description excel表格文件读取器
 */
@Component
public class FileHandler {

    public static final String EXCEL_XLSX = "xlsx";

    public static final String FTL = "ftl";
    /**
     * <key>ExcelReader reference address</key>
     * <value>directory</value>
     */
    private final Map<String,String> fileContext = new HashMap<>();

    private String vmMacroTemplates;

    private String getRootPath() {
        return FileHandler.class.getProtectionDomain()
                .getCodeSource().getLocation().getPath();
    }

    public List<File> getFiles(String filterSuffix,String path){
        String rootPath = getRootPath();
        if (StrUtil.isNotBlank(path)){
            rootPath += path;
        }
        File rootFile = new File(rootPath);
        if (rootFile.isFile()){
            if (filterSuffix.equals(FileUtil.getSuffix(rootFile))){
                return ListUtil.toList(rootFile);
            }
            return null;
        }
        File[] files = FileUtil.file(rootFile).listFiles();
        if (files == null || files.length == 0) {
            return new ArrayList<>();
        }
        if (StrUtil.isBlank(filterSuffix)){
            return ListUtil.toList(files);
        }
        return Arrays.stream(files).filter(file -> {
            String suffix = FileUtil.getSuffix(file);
            return filterSuffix.equals(suffix);
        }) .collect(Collectors.toList());
    }

    public List<ExcelReader> readExcels() {
        List<ExcelReader> excelReaders = new ArrayList<>();
        List<File> files = getFiles(EXCEL_XLSX,null);
        files.forEach(file -> {
            if (file.getName().startsWith("~")){
                return;
            }
            ExcelReader excelReader = ExcelUtil.getReader(file);
            if (ExcelParser.checkExcelIsValid(excelReader)) {
                createDir(excelReader,file);
                excelReaders.add(excelReader);
            }
        });
        return excelReaders;
    }

    public String readTemplates(String path){
        if (StrUtil.isBlank(path)){
            if (StrUtil.isNotBlank(vmMacroTemplates)){
                return vmMacroTemplates;
            }
            List<File> files = getFiles(FTL,path);
            vmMacroTemplates = files.stream().map(file -> FileReader.create(file).readString())
                    .collect(Collectors.joining());
            return vmMacroTemplates;
        }else{
            return getFiles(FTL,path).stream().map(file -> FileReader.create(file).readString())
                    .collect(Collectors.joining());
        }
    }

    private void createDir(ExcelReader excelReader,File excelFile) {
        String prefix = FileUtil.getPrefix(excelFile);
        String dirPath = getRootPath() + prefix + "_"
                + DateUtil.format(new Date(),"yyyyMMddHHmmss");
        File dir = FileUtil.mkdir(dirPath);
        FileCopier.create(excelFile,dir).copy();
        fileContext.put(excelReader.toString(),dir.getAbsolutePath());
    }

    public void write(List<GenerateResult> generateResults) {
        for (GenerateResult generateResult : generateResults) {
            ExcelParserResult excelParserResult = generateResult.getExcelParserResult();
            ExcelReader excelReader = excelParserResult.getExcelReader();
            String dir = fileContext.get(excelReader.toString());
            String fileName = getFileName(generateResult);
            if (FileUtil.isAbsolutePath(fileName)){
                FileWriter.create(new File(fileName)).write(generateResult.getContent());
                fileName = FileUtil.getName(fileName);
            }
            fileName = dir + File.separator + fileName;
            FileWriter.create(new File(fileName)).write(generateResult.getContent());
        }
    }

    private String getFileName(GenerateResult generateResult){
        AtomicReference<String> fileName = new AtomicReference<>(generateResult.getSheetName());
        generateResult.getExcelParserResult().getConfig().getSheetFileConfig().stream()
                .filter(sheetFileConfig -> sheetFileConfig.getSheetName().equals(generateResult.getSheetName()))
                .findFirst().ifPresent(sheetFileConfig -> fileName.set(sheetFileConfig.getFileName()));
        return fileName.get();
    }

    public void writeLog(ExcelReader excelReader,String message){
        String dir = fileContext.get(excelReader.toString());
        String logFile = dir + File.separator + "log.txt";
        FileWriter.create(new File(logFile)).write(message);
    }
}
